home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / Portable Patmos / src / portable kernel / ncsasock / unixlib.c < prev   
Encoding:
C/C++ Source or Header  |  1994-01-06  |  15.1 KB  |  618 lines  |  [TEXT/R*ch]

  1. /*
  2.  * BSD-style socket emulation library for the Mac
  3.  * Original author: Tom Milligan
  4.  * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
  5.  *
  6.  * This source file is placed in the public domian.
  7.  * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
  8.  *
  9.  *      National Center for Supercomputing Applications
  10.  *      152 Computing Applications Building
  11.  *      605 E. Springfield Ave.
  12.  *      Champaign, IL  61820
  13.  */
  14.  
  15. #ifdef USEDUMP
  16. # pragma load "socket.dump"
  17. #else
  18. # include <Errors.h>
  19. # include <Events.h>
  20. # include <Files.h>
  21. # include <OSUtils.h>
  22. # include <Types.h>
  23.  
  24. # include <s_types.h>
  25. # include <s_time.h>
  26.  
  27. #endif
  28.  
  29. #include <FCntl.h>
  30. #include <neti_in.h>
  31. #include <sock_ext.h>
  32. #include <sock_str.h>
  33. #ifdef THINK_C
  34. #include <pascal.h>
  35. #else
  36. #include <Strings.h>  /* for c2pstr */
  37. #endif /* THINK_C */
  38. #include <ToolUtils.h>
  39.  
  40. #include <s_timeb.h>
  41.  
  42. extern int errno;
  43. extern long errno_long;
  44. extern SpinFn spinroutine; 
  45.  
  46. /*
  47.  * unix getwd
  48.  *
  49.  *    where must point to 256 bytes
  50.  *    
  51.  *    work up from the current directory to the root collecting 
  52.  *    name segments as we go
  53.  */
  54.  
  55. char *getwd(where) char *where;
  56. {
  57.     WDPBRec pb;
  58.     CInfoPBRec cpb;
  59.     char wdtemp[256],*start,*store,*trav;
  60.     int i;
  61.  
  62.     /* get default volume and directory last set by PBSetVol or PBHSetVol */
  63.     pb.ioNamePtr = (StringPtr) where;
  64.     PBHGetVol(&pb,false);
  65.  
  66.     /* add a colon */
  67.     (*where)++;
  68.     where[*where] = ':';
  69.     
  70.     trav = wdtemp; /* build name here */
  71.     cpb.dirInfo.ioCompletion = 0L;
  72.  
  73.     cpb.dirInfo.ioVRefNum = pb.ioWDVRefNum; /* vRefNum of volume on which */
  74.                                             /* working dir exists */
  75.     
  76.     cpb.dirInfo.ioDrDirID = pb.ioWDDirID; /* directory ID of working directory */
  77.     
  78.     while(cpb.dirInfo.ioDrDirID != 0) 
  79.     {
  80.         cpb.hFileInfo.ioNamePtr = (StringPtr) trav; /* put name segment here */
  81.         cpb.hFileInfo.ioFDirIndex = -1;
  82.         if (PBGetCatInfo(&cpb,false) != 0)  
  83.         {
  84.             cpb.dirInfo.ioDrDirID = 0;
  85.             break;
  86.         }
  87.         if (*trav == 0) 
  88.         {
  89.             cpb.dirInfo.ioDrDirID=0;
  90.             break;
  91.         }
  92.         i=*trav;      /* save length */
  93.         *trav=0;      /* null over length */
  94.         start=trav+1; /* addr of 1st char */
  95.         trav+=i+1;    /* point past current string for next name segment */ 
  96.         *trav=0;      /* initially zero length */
  97.  
  98.         cpb.dirInfo.ioDrDirID = cpb.dirInfo.ioDrParID; /* point up to parent directory */
  99.     }
  100.     
  101.     *wdtemp=0;
  102.     store=where+*where+1; /* start storing after volume name */
  103.     
  104.     if (trav-wdtemp) 
  105.         *where=(trav-wdtemp); /* set length of where as length of trav */
  106.     if (trav!=wdtemp) 
  107.         start=trav-1; 
  108.     else 
  109.         start=wdtemp;
  110.  
  111.     if (start!=wdtemp) 
  112.     {
  113.         while(*start) start--;        /* Go to beginning of string */
  114.         if (start!=wdtemp) 
  115.             start--;
  116.     }
  117.  
  118.     while(start!=wdtemp) 
  119.     {
  120.         while(*start) /* Go to beginning of string */
  121.             start--;        
  122.         trav=start+1; 
  123.         while (*trav)  /* store it */
  124.         {
  125.             *store=*trav; 
  126.             store++;
  127.             trav++; 
  128.         } 
  129.         *store=':';    /* Ready to move directory name */
  130.         store++;
  131.         if (start!=wdtemp) 
  132.             start--;
  133.         *store=0;
  134.     }    
  135.     return(p2cstr((unsigned char *) where));
  136. }
  137.  
  138. /*
  139.  * unix change working directory
  140.  */
  141. static int currentWD = 0;
  142.  
  143. int chdir(pathName) char *pathName;
  144. {
  145.     WDPBRec pb;
  146.     char tempst[256];
  147.     long default_ioWDDirID;
  148.     short wdToClose;
  149.  
  150.     /* 
  151.      * get default volume last set by PBSetVol or PBHSetVol 
  152.      */
  153.     pb.ioNamePtr = 0L;
  154.     PBHGetVol(&pb,false);
  155.     default_ioWDDirID = pb.ioWDDirID;
  156.  
  157.     /*
  158.      * create a new mac working directory using the default volume and
  159.      * the callers partial pathname
  160.      */
  161.     strcpy(tempst,pathName);
  162.     pb.ioNamePtr = (StringPtr)c2pstr(tempst);
  163.     pb.ioVRefNum = 0;
  164.     pb.ioWDDirID = default_ioWDDirID;
  165.     pb.ioCompletion = 0L;
  166.     pb.ioWDProcID = 'UTCS';
  167.  
  168.     if ((errno = errno_long = PBOpenWD(&pb,0)) != noErr) 
  169.         return(-1);
  170.     
  171.     /*
  172.      * make the mac working directory which has just been created in 'pb'
  173.      * the new default directory. destroy the mac working directory which
  174.      * was the previous default.
  175.      */
  176. #ifdef THINK_C
  177.     if ((errno = errno_long = SetVol(0L, pb.ioVRefNum)) != noErr) 
  178. #else
  179.     if ((errno = errno_long = setvol(0L, pb.ioVRefNum)) != noErr) 
  180. #endif
  181.     {
  182.         wdToClose = pb.ioVRefNum;
  183.     } 
  184.     else 
  185.     {
  186.         wdToClose = currentWD;
  187.         currentWD = pb.ioVRefNum;
  188.     }
  189.  
  190.     /*
  191.      * close the previous working directory
  192.      */
  193.     if (wdToClose == 0)    /* nothing more to do, return */
  194.         return(0);
  195.  
  196.     pb.ioVRefNum = wdToClose;
  197.     pb.ioCompletion = 0L;
  198.     (void) PBCloseWD(&pb, false); /* ignore error */
  199.     
  200.     return(0);
  201. }
  202.  
  203. /*
  204.  * Mac version of Unix system call gettimeofday. 
  205.  *
  206.  * Time is converted to the Unix epoch: Jan 1, 1970.
  207.  *
  208.  * The current timezone is always GMT.
  209.  */
  210.  
  211. static struct DateTimeRec unixEpochDtr = {1970,1,1, 0,0,0, 1};
  212. gettimeofday(tp,tzp) struct timeval *tp; struct timezone *tzp;
  213. {
  214.  
  215.     unsigned long unixEpochSecs,currentMacSecs;
  216.     
  217.     Date2Secs(&unixEpochDtr,&unixEpochSecs);
  218.     GetDateTime(¤tMacSecs);
  219.     tp->tv_sec = currentMacSecs - unixEpochSecs;
  220.     tp->tv_usec = 0;
  221.  
  222.     if (tzp != NULL)
  223.     {
  224.         tzp->tz_minuteswest = 0;    /* minutes west of Greenwich */
  225.         tzp->tz_dsttime = 0;    /* no dst correction */
  226.     }
  227. }
  228.  
  229. #if 0
  230. /*
  231.  * Backwards compatible time call.
  232.  */
  233. time_t
  234. time(t)
  235.     time_t *t;
  236. {
  237.     struct timeval tt;
  238.  
  239.     if (gettimeofday(&tt, (struct timezone *)0) < 0)
  240.         return (-1);
  241.     if (t)
  242.         *t = tt.tv_sec;
  243.     return (tt.tv_sec);
  244. }
  245. #endif
  246.  
  247.  
  248. /*
  249.  * The arguments are the number of minutes of time
  250.  * you are westward from Greenwich and whether DST is in effect.
  251.  * It returns a string
  252.  * giving the name of the local timezone.
  253.  *
  254.  * Sorry, I don't know all the names.
  255.  */
  256.  
  257. static struct zone {
  258.     int    offset;
  259.     char    *stdzone;
  260.     char    *dlzone;
  261. } zonetab[] = {
  262.     -1*60, "MET", "MET DST",    /* Middle European */
  263.     -2*60, "EET", "EET DST",    /* Eastern European */
  264.     4*60, "AST", "ADT",        /* Atlantic */
  265.     5*60, "EST", "EDT",        /* Eastern */
  266.     6*60, "CST", "CDT",        /* Central */
  267.     7*60, "MST", "MDT",        /* Mountain */
  268.     8*60, "PST", "PDT",        /* Pacific */
  269. #ifdef notdef
  270.     /* there's no way to distinguish this from WET */
  271.     0, "GMT", 0,            /* Greenwich */
  272. #endif
  273.     0*60, "WET", "WET DST",        /* Western European */
  274.     -10*60, "EST", "EST",        /* Aust: Eastern */
  275.     -10*60+30, "CST", "CST",    /* Aust: Central */
  276.     -8*60, "WST", 0,        /* Aust: Western */
  277.     -9*60, "JST", 0,        /* Japanese */
  278.     -1
  279. };
  280.  
  281. char *timezone(zone, dst)
  282. {
  283.     register struct zone *zp;
  284.     static char czone[10];
  285.     char *sign;
  286.     register char *p, *q;
  287.     char *getenv(), *strchr();
  288.  
  289.     if (p = getenv("TZNAME")) {
  290.         if (q = strchr(p, ',')) {
  291.             if (dst)
  292.                 return(++q);
  293.             else {
  294.                 *q = '\0';
  295.                 strncpy(czone, p, sizeof(czone)-1);
  296.                 czone[sizeof(czone)-1] = '\0';
  297.                 *q = ',';
  298.                 return (czone);
  299.             }
  300.         }
  301.         return(p);
  302.     }
  303.     for (zp=zonetab; zp->offset!=-1; zp++)
  304.         if (zp->offset==zone) {
  305.             if (dst && zp->dlzone)
  306.                 return(zp->dlzone);
  307.             if (!dst && zp->stdzone)
  308.                 return(zp->stdzone);
  309.         }
  310.     if (zone<0) {
  311.         zone = -zone;
  312.         sign = "+";
  313.     } else
  314.         sign = "-";
  315.     sprintf(czone, "GMT%s%d:%02d", sign, zone/60, zone%60);
  316.     return(czone);
  317. }
  318.  
  319. #ifdef JAE
  320. /*
  321.  * Sleep now calls the spinroutine to keep things
  322.  * moving
  323.  */
  324. sleep(seconds) unsigned seconds;
  325.     {
  326.     long int wakeup = TickCount() + 60*seconds;
  327.     long left;
  328.     
  329.     for (;;)
  330.         {
  331.         left = wakeup-TickCount();
  332.         
  333.         if (left <= 0)
  334.             return;
  335.             
  336.         SPIN(false,SP_SLEEP,left)
  337.         }
  338.     }
  339. #endif /* JAE */
  340.  
  341. #if 0
  342. long int getpid()
  343. {
  344.     return (42);
  345. }
  346. #endif
  347.  
  348. long int getuid()
  349. {
  350.     return (0/*root*/);
  351. }
  352.  
  353. struct passwd *getpwent()
  354. {
  355.     return (NULL/*not found*/);
  356. }
  357.  
  358. struct passwd *getpwuid()
  359. {
  360.     return (NULL/*not found*/);
  361. }
  362.  
  363. struct passwd *getpwnam()
  364. {
  365.     return (NULL/*not found*/);
  366. }
  367.  
  368. #ifdef JAE
  369. char *getlogin()
  370. {
  371.     return("macuser");
  372. }
  373. #endif /* JAE */
  374.  
  375. int chmod(path, mode)
  376.     char *path;
  377.     int mode;
  378. {
  379. #pragma unused(path)
  380. #pragma unused(mode)
  381.     return(0);
  382. }
  383.  
  384. #if 0
  385. access(path, mode)
  386.     char *path;
  387.     int mode;
  388. {
  389. #pragma unused(path)
  390. #pragma unused(mode)
  391.     return(0);
  392. }
  393.  
  394. char *mktemp(template)
  395.     char *template;
  396. {
  397.     return(template);
  398. }
  399.  
  400. abort()
  401. {
  402.     exit(-1);
  403. }
  404. #endif
  405.  
  406. void bzero( b, s)
  407.     char *b;
  408.     long s;
  409. {
  410.     for( ; s ; ++b, --s)
  411.         *b = 0;
  412. }
  413.  
  414. bfill( b, s, fill)
  415.     char *b;
  416.     long s;
  417.     char fill;
  418. {
  419.     for( ; s ; ++b, --s)
  420.         *b = fill;
  421. }
  422.  
  423. void bcopy (c1, c2, s)
  424.     char        *c1, *c2;
  425.     long        s;
  426. {
  427.     for ( ; s ; --s)
  428.         *c2++ = *(c1++);
  429. }
  430.  
  431.  
  432. bcmp (c1, c2, s)
  433.     char        *c1, *c2;
  434.     long        s;
  435. {
  436.     for ( ; s ; --s)
  437.         if(*c2++ != *(c1++)) return(1);
  438.     return(0);
  439. }
  440.  
  441. char    *sys_errlist[] = {
  442.     "Error 0",
  443.     "Not owner",                /* 1 - EPERM */
  444.     "No such file or directory",        /* 2 - ENOENT */
  445.     "No such process",            /* 3 - ESRCH */
  446.     "Interrupted system call",        /* 4 - EINTR */
  447.     "I/O error",                /* 5 - EIO */
  448.     "No such device or address",        /* 6 - ENXIO */
  449.     "Arg list too long",            /* 7 - E2BIG */
  450.     "Exec format error",            /* 8 - ENOEXEC */
  451.     "Bad file number",            /* 9 - EBADF */
  452.     "No children",                /* 10 - ECHILD */
  453.     "No more processes",            /* 11 - EAGAIN */
  454.     "Not enough core",            /* 12 - ENOMEM */
  455.     "Permission denied",            /* 13 - EACCES */
  456.     "Bad address",                /* 14 - EFAULT */
  457.     "Block device required",        /* 15 - ENOTBLK */
  458.     "Mount device busy",            /* 16 - EBUSY */
  459.     "File exists",                /* 17 - EEXIST */
  460.     "Cross-device link",            /* 18 - EXDEV */
  461.     "No such device",            /* 19 - ENODEV */
  462.     "Not a directory",            /* 20 - ENOTDIR */
  463.     "Is a directory",            /* 21 - EISDIR */
  464.     "Invalid argument",            /* 22 - EINVAL */
  465.     "File table overflow",            /* 23 - ENFILE */
  466.     "Too many open files",            /* 24 - EMFILE */
  467.     "Not a typewriter",            /* 25 - ENOTTY */
  468.     "Text file busy",            /* 26 - ETXTBSY */
  469.     "File too large",            /* 27 - EFBIG */
  470.     "No space left on device",        /* 28 - ENOSPC */
  471.     "Illegal seek",                /* 29 - ESPIPE */
  472.     "Read-only file system",        /* 30 - EROFS */
  473.     "Too many links",            /* 31 - EMLINK */
  474.     "Broken pipe",                /* 32 - EPIPE */
  475.  
  476. /* math software */
  477.     "Argument too large",            /* 33 - EDOM */
  478.     "Result too large",            /* 34 - ERANGE */
  479.  
  480. /* non-blocking and interrupt i/o */
  481.     "Operation would block",        /* 35 - EWOULDBLOCK */
  482.     "Operation now in progress",        /* 36 - EINPROGRESS */
  483.     "Operation already in progress",    /* 37 - EALREADY */
  484.  
  485. /* ipc/network software */
  486.  
  487.     /* argument errors */
  488.     "Socket operation on non-socket",    /* 38 - ENOTSOCK */
  489.     "Destination address required",        /* 39 - EDESTADDRREQ */
  490.     "Message too long",            /* 40 - EMSGSIZE */
  491.     "Protocol wrong type for socket",    /* 41 - EPROTOTYPE */
  492.     "Protocol not available",        /* 42 - ENOPROTOOPT */
  493.     "Protocol not supported",        /* 43 - EPROTONOSUPPORT */
  494.     "Socket type not supported",        /* 44 - ESOCKTNOSUPPORT */
  495.     "Operation not supported on socket",    /* 45 - EOPNOTSUPP */
  496.     "Protocol family not supported",    /* 46 - EPFNOSUPPORT */
  497.     "Address family not supported by protocol family",
  498.                         /* 47 - EAFNOSUPPORT */
  499.     "Address already in use",        /* 48 - EADDRINUSE */
  500.     "Can't assign requested address",    /* 49 - EADDRNOTAVAIL */
  501.  
  502.     /* operational errors */
  503.     "Network is down",            /* 50 - ENETDOWN */
  504.     "Network is unreachable",        /* 51 - ENETUNREACH */
  505.     "Network dropped connection on reset",    /* 52 - ENETRESET */
  506.     "Software caused connection abort",    /* 53 - ECONNABORTED */
  507.     "Connection reset by peer",        /* 54 - ECONNRESET */
  508.     "No buffer space available",        /* 55 - ENOBUFS */
  509.     "Socket is already connected",        /* 56 - EISCONN */
  510.     "Socket is not connected",        /* 57 - ENOTCONN */
  511.     "Can't send after socket shutdown",    /* 58 - ESHUTDOWN */
  512.     "Too many references: can't splice",    /* 59 - ETOOMANYREFS */
  513.     "Connection timed out",            /* 60 - ETIMEDOUT */
  514.     "Connection refused",            /* 61 - EREFUSED */
  515.     "Too many levels of symbolic links",    /* 62 - ELOOP */
  516.     "File name too long",            /* 63 - ENAMETOOLONG */
  517.     "Host is down",                /* 64 - EHOSTDOWN */
  518.     "Host is unreachable",            /* 65 - EHOSTUNREACH */
  519.     "Directory not empty",            /* 66 - ENOTEMPTY */
  520.     "Too many processes",            /* 67 - EPROCLIM */
  521.     "Too many users",            /* 68 - EUSERS */
  522.     "Disc quota exceeded",            /* 69 - EDQUOT */
  523.     "Stale NFS file handle",        /* 70 - ESTALE */
  524.     "Too many levels of remote in path",    /* 71 - EREMOTE */
  525. };
  526.  
  527. int    sys_nerr = { sizeof sys_errlist/sizeof sys_errlist[0] };
  528.  
  529. /*
  530.  * Copyright (c) 1987 Regents of the University of California.
  531.  * All rights reserved.
  532.  *
  533.  * Redistribution and use in source and binary forms are permitted
  534.  * provided that the above copyright notice and this paragraph are
  535.  * duplicated in all such forms and that any documentation,
  536.  * advertising materials, and other materials related to such
  537.  * distribution and use acknowledge that the software was developed
  538.  * by the University of California, Berkeley.  The name of the
  539.  * University may not be used to endorse or promote products derived
  540.  * from this software without specific prior written permission.
  541.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  542.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  543.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  544.  */
  545.  
  546. #if defined(LIBC_SCCS) && !defined(lint)
  547. static char sccsid[] = "@(#)strcasecmp.c    5.6 (Berkeley) 6/27/88";
  548. #endif /* LIBC_SCCS and not lint */
  549.  
  550. #include <s_types.h>
  551.  
  552. /*
  553.  * This array is designed for mapping upper and lower case letter
  554.  * together for a case independent comparison.  The mappings are
  555.  * based upon ascii character sequences.
  556.  */
  557. static u_char charmap[] = {
  558.     '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
  559.     '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
  560.     '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
  561.     '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
  562.     '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
  563.     '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
  564.     '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
  565.     '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
  566.     '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  567.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  568.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  569.     '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
  570.     '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  571.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  572.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  573.     '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
  574.     '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
  575.     '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
  576.     '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
  577.     '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
  578.     '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
  579.     '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
  580.     '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
  581.     '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
  582.     '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  583.     '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  584.     '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  585.     '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
  586.     '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  587.     '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  588.     '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  589.     '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
  590. };
  591.  
  592. strcasecmp(s1, s2)
  593.     char *s1, *s2;
  594. {
  595.     register u_char    *cm = charmap,
  596.             *us1 = (u_char *)s1,
  597.             *us2 = (u_char *)s2;
  598.  
  599.     while (cm[*us1] == cm[*us2++])
  600.         if (*us1++ == '\0')
  601.             return(0);
  602.     return(cm[*us1] - cm[*--us2]);
  603. }
  604.  
  605. strncasecmp(s1, s2, n)
  606.     char *s1, *s2;
  607.     register int n;
  608. {
  609.     register u_char    *cm = charmap,
  610.             *us1 = (u_char *)s1,
  611.             *us2 = (u_char *)s2;
  612.  
  613.     while (--n >= 0 && cm[*us1] == cm[*us2++])
  614.         if (*us1++ == '\0')
  615.             return(0);
  616.     return(n < 0 ? 0 : cm[*us1] - cm[*--us2]);
  617. }
  618.